{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import paddle\n",
    "import paddle.fluid as fluid\n",
    "from paddle.fluid.dygraph import Linear\n",
    "import numpy as np\n",
    "import utils\n",
    "\n",
    "import matplotlib\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "from IPython import display\n",
    "from PIL import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def draw_line(costs, learning_rate):\n",
    "    \"\"\"\n",
    "    动态绘制训练中costs的曲线\n",
    "    :param costs: 记录了训练过程的cost变化的list\n",
    "    \"\"\"\n",
    "    plt.clf()\n",
    "    plt.plot(costs)\n",
    "    plt.title(\"Learning rate = %f\" % (learning_rate))\n",
    "    plt.ylabel('cost')\n",
    "    plt.xlabel('iterations')\n",
    "    plt.pause(0.05)\n",
    "    display.clear_output(wait=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_data():\n",
    "    \"\"\"\n",
    "    数据预处理\n",
    "    \"\"\"\n",
    "    # 获取原始数据\n",
    "    train_x_ori, train_y_set, test_x_ori, test_y_set, classes = utils.load_data_sets()\n",
    "    # m_train: 训练集样本数量\n",
    "    m_train = train_x_ori.shape[0]\n",
    "    # m_test: 测试集样本数量\n",
    "    m_test = test_x_ori.shape[0]\n",
    "    # 图片样本长宽像素数量\n",
    "    num_px_x = train_x_ori.shape[1]\n",
    "    num_px_y = train_x_ori.shape[2]\n",
    "\n",
    "    # 定义输入数据维度，注意样本图像是3通道\n",
    "    DATA_DIM = num_px_x * num_px_y * 3\n",
    "\n",
    "    # 转换数据形状为\n",
    "    train_x_flatten = train_x_ori.reshape(m_train, -1)\n",
    "    test_x_flatten = test_x_ori.reshape(m_test, -1)\n",
    "\n",
    "    # 归一化处理\n",
    "    train_x_set = train_x_flatten / 255\n",
    "    test_x_set = test_x_flatten / 255\n",
    "\n",
    "    # 合并数据\n",
    "    train_set = np.hstack((train_x_set, train_y_set.T))\n",
    "    test_set = np.hstack((test_x_set, test_y_set.T))\n",
    "\n",
    "    return train_set, test_set, DATA_DIM, classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取数据集以及相关参数\n",
    "global TRAIN_SET\n",
    "global TEST_SET\n",
    "global DATA_DIM\n",
    "global CLASSES\n",
    "TRAIN_SET, TEST_SET, DATA_DIM, CLASSES = get_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_data(data_set):\n",
    "    \"\"\"\n",
    "    构造reader\n",
    "    :param data_set: 要获取的数据的数据集\n",
    "    :return: reader: 用户返回训练数据及数据标签的生成器(generator)\n",
    "    \"\"\"\n",
    "    def reader():\n",
    "        \"\"\"\n",
    "        一个reader生成器\n",
    "        :return: 每次训练数据及数据标签\n",
    "        data[:-1]: 训练数据\n",
    "        data[-1:]: 数据标签\n",
    "        \"\"\"\n",
    "        for data in data_set:\n",
    "            yield data[:-1], data[-1:]\n",
    "    return reader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义reader\n",
    "# 定义buf_size和batch_size大小\n",
    "buf_size = 1000\n",
    "batch_size = 256\n",
    "\n",
    "# 训练集reader\n",
    "train_reader = fluid.io.batch(\n",
    "    reader=paddle.reader.shuffle(\n",
    "        reader=read_data(TRAIN_SET),\n",
    "        buf_size=buf_size\n",
    "    ),\n",
    "    batch_size=batch_size\n",
    ")\n",
    "# 测试集reader\n",
    "test_reader = fluid.io.batch(\n",
    "    reader=paddle.reader.shuffle(\n",
    "        reader=read_data(TEST_SET),\n",
    "        buf_size=buf_size\n",
    "    ),\n",
    "    batch_size=batch_size\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义softmax分类器\n",
    "class SoftmaxRegression(fluid.dygraph.Layer):\n",
    "    def __init__(self, name_scope):\n",
    "        super(SoftmaxRegression, self).__init__(name_scope)\n",
    "        # 输出层，全连接层，输出大小为2，对应结果的两个类别，激活函数为softmax\n",
    "        self.fc = Linear(input_dim=DATA_DIM, output_dim=2, act='softmax')\n",
    "        \n",
    "    \n",
    "    # 网络的前向计算函数\n",
    "    def forward(self, x):\n",
    "        x = self.fc(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义飞桨动态图工作环境\n",
    "with fluid.dygraph.guard():\n",
    "    # 实例化模型\n",
    "    # Softmax分类器\n",
    "    model = SoftmaxRegression('catornocat')\n",
    "    \n",
    "    # 开启模型训练模式\n",
    "    model.train()\n",
    "    # 使用Adam优化器\n",
    "    # 学习率为0.01\n",
    "    opt = fluid.optimizer.Adam(learning_rate=0.01, parameter_list=model.parameters())\n",
    "    # 迭代次数设为200\n",
    "    EPOCH_NUM = 200\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "with fluid.dygraph.guard():\n",
    "    # 记录每次的损失值，用于绘图\n",
    "    costs = []\n",
    "    # 定义外层循环\n",
    "    for pass_num in range(EPOCH_NUM):\n",
    "        # 定义内层循环\n",
    "        for batch_id,data in enumerate(train_reader()):\n",
    "            # 调整数据shape使之适合模型\n",
    "            images = np.array([x[0].reshape(DATA_DIM) for x in data],np.float32)\n",
    "            labels = np.array([x[1] for x in data]).astype('int64').reshape(-1,1)\n",
    "            \n",
    "            # 将numpy数据转为飞桨动态图variable形式\n",
    "            image = fluid.dygraph.to_variable(images)\n",
    "            label = fluid.dygraph.to_variable(labels)\n",
    "            \n",
    "            # 前向计算\n",
    "            predict = model(image)\n",
    "\n",
    "            # 计算损失\n",
    "            # 使用交叉熵损失函数\n",
    "            loss = fluid.layers.cross_entropy(predict,label)\n",
    "            avg_loss = fluid.layers.mean(loss)\n",
    "\n",
    "            # 计算精度\n",
    "            # acc = fluid.layers.accuracy(predict,label)\n",
    "            \n",
    "            # 绘图\n",
    "            costs.append(avg_loss.numpy()[0])\n",
    "            draw_line(costs, 0.01)\n",
    "\n",
    "            # 反向传播\n",
    "            avg_loss.backward()\n",
    "            # 最小化loss,更新参数\n",
    "            opt.minimize(avg_loss)\n",
    "            # 清除梯度\n",
    "            model.clear_gradients()\n",
    "\n",
    "    # 保存模型文件到指定路径\n",
    "    fluid.save_dygraph(model.state_dict(), 'catornocat')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "index 0, truth 1, infer 1\n",
      "index 1, truth 1, infer 1\n",
      "index 2, truth 0, infer 0\n",
      "index 3, truth 0, infer 1\n",
      "index 4, truth 0, infer 0\n",
      "index 5, truth 1, infer 1\n",
      "index 6, truth 1, infer 0\n",
      "index 7, truth 1, infer 1\n",
      "index 8, truth 0, infer 1\n",
      "index 9, truth 1, infer 1\n",
      "index 10, truth 1, infer 1\n",
      "index 11, truth 1, infer 1\n",
      "index 12, truth 1, infer 1\n",
      "index 13, truth 1, infer 1\n",
      "index 14, truth 0, infer 1\n",
      "index 15, truth 0, infer 0\n",
      "index 16, truth 0, infer 0\n",
      "index 17, truth 0, infer 0\n",
      "index 18, truth 1, infer 1\n",
      "index 19, truth 1, infer 0\n",
      "index 20, truth 1, infer 0\n",
      "index 21, truth 1, infer 1\n",
      "index 22, truth 0, infer 1\n",
      "index 23, truth 0, infer 0\n",
      "index 24, truth 1, infer 0\n",
      "index 25, truth 1, infer 1\n",
      "index 26, truth 1, infer 0\n",
      "index 27, truth 0, infer 0\n",
      "index 28, truth 0, infer 0\n",
      "index 29, truth 1, infer 0\n",
      "index 30, truth 1, infer 1\n",
      "index 31, truth 1, infer 0\n",
      "index 32, truth 0, infer 1\n",
      "index 33, truth 1, infer 0\n",
      "index 34, truth 1, infer 1\n",
      "index 35, truth 1, infer 1\n",
      "index 36, truth 1, infer 0\n",
      "index 37, truth 0, infer 0\n",
      "index 38, truth 1, infer 1\n",
      "index 39, truth 1, infer 1\n",
      "index 40, truth 0, infer 1\n",
      "index 41, truth 0, infer 0\n",
      "index 42, truth 1, infer 1\n",
      "index 43, truth 1, infer 0\n",
      "index 44, truth 1, infer 1\n",
      "index 45, truth 1, infer 1\n",
      "index 46, truth 0, infer 0\n",
      "index 47, truth 1, infer 1\n",
      "index 48, truth 1, infer 0\n",
      "index 49, truth 1, infer 1\n",
      "test accuracy 66.0%\n"
     ]
    }
   ],
   "source": [
    "# 模型评估\n",
    "with fluid.dygraph.guard():\n",
    "    # 读取模型\n",
    "    # 参数为保存模型参数的文件地址\n",
    "    model_dict, _ = fluid.load_dygraph('catornocat')\n",
    "    # 加载模型参数\n",
    "    model.load_dict(model_dict)\n",
    "    #评估模式\n",
    "    model.eval()\n",
    "    \n",
    "    # 读取测试集数据\n",
    "    data = next(test_reader())\n",
    "\n",
    "    # 调整数据shape使之适合模型\n",
    "    images = np.array([x[0].reshape(DATA_DIM) for x in data],np.float32)\n",
    "    labels = np.array([x[1] for x in data]).astype('int64').reshape(1, -1)[0]\n",
    "    \n",
    "    # 将numpy数据转为飞桨动态图variable形式\n",
    "    image = fluid.dygraph.to_variable(images)\n",
    "    \n",
    "    # 前向计算\n",
    "    predict = model(image)\n",
    "\n",
    "    # 统计预测结果\n",
    "    # 将预测结果转为numpy数据类型\n",
    "    predict = predict.numpy()\n",
    "    predict = np.argmax(predict, axis = 1)\n",
    "    \n",
    "    # 记录预测正确的样本数量\n",
    "    num = 0\n",
    "    for index in range(len(predict)):\n",
    "        if labels[index] == predict[index]:\n",
    "            num += 1    \n",
    "        print(\"index {}, truth {}, infer {}\".format(index, labels[index], predict[index]))\n",
    "    print(\"test accuracy {}%\".format(num/len(predict)*100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "The label of this picture is 1.0, 1 means it's a cat picture, 0 means not \n",
      "You predict that it's a cat picture. \n",
      "Congrats!\n"
     ]
    }
   ],
   "source": [
    "# 使用单张图片测试\n",
    "# 预览测试图片\n",
    "index = 11\n",
    "image = np.reshape(TEST_SET[index][:-1], (64, 64, 3))\n",
    "plt.imshow(image)\n",
    "plt.show()\n",
    "print(\n",
    "        \"\\nThe label of this picture is \" + str(TEST_SET[index, -1])\n",
    "        + \", 1 means it's a cat picture, 0 means not \"\n",
    "        + \"\\nYou predict that it's a \"\n",
    "        + CLASSES[int(predict[index])].decode(\"utf-8\")\n",
    "        + \" picture. \\nCongrats!\"\n",
    "    )"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}